#include "ram.h"
#include "memmap.h"
#include <string.h>

static uint8_t ram[RAM_SIZE];

sts ram_init(void)
{
    memset(ram, 0, RAM_SIZE);
    return OK;
}

sts ram_write_b(uint32_t addr, uint8_t data)
{
    uint32_t _addr = addr & 0xFFFFFF;
    if (_addr > RAM_SIZE - 1)
    {
        return INVALID;
    }
    ram[_addr] = data;
    return OK;
}

sts ram_write_h(uint32_t addr, uint16_t data)
{
    uint32_t _addr = addr & 0xFFFFFF;
    if (_addr > RAM_SIZE - 1)
    {
        return INVALID;
    }
    ram[_addr] = data & 0xFF;
    ram[_addr + 1] = (data >> 8) & 0xFF;
    return OK;
}

sts ram_write_w(uint32_t addr, uint32_t data)
{
    uint32_t _addr = addr & 0xFFFFFF;
    if (_addr > RAM_SIZE - 1)
    {
        return INVALID;
    }
    // 判断是否对其
    if (_addr & 0x3)
    {
        return INVALID;
    }
    ram[_addr] = data & 0xFF;
    ram[_addr + 1] = (data >> 8) & 0xFF;
    ram[_addr + 2] = (data >> 16) & 0xFF;
    ram[_addr + 3] = (data >> 24) & 0xFF;
    return OK;
}

sts ram_read_b(uint32_t addr, uint8_t *data)
{
    uint32_t _addr = addr & 0xFFFFFF;
    if (_addr > RAM_SIZE - 1)
    {
        return INVALID;
    }
    *data = ram[_addr];
    return OK;
}

sts ram_read_h(uint32_t addr, uint16_t *data)
{
    uint32_t _addr = addr & 0xFFFFFF;
    if (_addr > RAM_SIZE - 1)
    {
        return INVALID;
    }
    *data = ram[_addr] | (ram[_addr + 1] << 8);
    return OK;
}

sts ram_read_w(uint32_t addr, uint32_t *data)
{
    uint32_t _addr = addr & 0xFFFFFF;
    if (_addr > RAM_SIZE - 1)
    {
        return INVALID;
    }
    // 判断是否对其
    if (_addr & 0x3)
    {
        return INVALID;
    }
    *data = ram[_addr] | (ram[_addr + 1] << 8) | (ram[_addr + 2] << 16) | (ram[_addr + 3] << 24);
    return OK;
}

struct device ram_dev = {
    .id = RAM_ID,
    .init = ram_init,
    .read_b = ram_read_b,
    .read_h = ram_read_h,
    .read_w = ram_read_w,
    .write_b = ram_write_b,
    .write_h = ram_write_h,
    .write_w = ram_write_w,
};
